using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SolarWinds.Helpers;
using SolarWinds.Input;

namespace SolarWinds.Widgets
{
    public class Window : TiledWidget
    {
        #region Public Properties

        private bool mResizable = true;

        public bool Resizeable
        {
            get { return mResizable; }
            set { mResizable = value; }
        }

        private bool mMoveable = true;
	
        public bool Moveable
        {
            get { return mMoveable; }
            set { mMoveable = value; }
        }

        private bool mHasCloseButton = true;

        public bool HasCloseButton
        {
            get { return mHasCloseButton; }
            set { mHasCloseButton = value; }
        }

        private Color mBackgroundColor = Color.Tomato;

        public Color BackgroundColor
        {
            get { return mBackgroundColor; }
            set { mBackgroundColor = value; }
        }

        #endregion

        public Window(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
        }

        protected internal override void PaintEvent()
        {
            base.PaintEvent();

            // strip string
            String stripCaption = SpriteFontHelper.StripString(Font, Caption, Width - 2 * mTileSize.X);

            Vector2 fontSize = Font.MeasureString(stripCaption);
            
            var pos = new Vector2(ScreenPosition.X + (Width - fontSize.X) / 2.0f,
                                  ScreenPosition.Y);// +Font.LineHeight;

            SpriteBatch.DrawString(Font, stripCaption, pos, TextColor);
        }

        protected override void InitializeRects()
        {
            mSrcRects = new Rectangle[10];
            mDestRects = new Rectangle[10];
            mTileColors = new Color[10];

            for (int i = 0; i < 10; ++i)
            {
                mTileColors[i] = Color.Tomato;
            }

            MinWidth = 2 * mTileSize.X;
            MinHeight = 2 * mTileSize.Y;
        }

        protected override void UpdateSrcDestRects()
        {
            // topLeft
            mSrcRects[0] = TileIndex2Rectangle(new Point(0, 1));
            mDestRects[0] = new Rectangle(ScreenPosition.X, ScreenPosition.Y, mTileSize.X, mTileSize.Y);
            // top
            mSrcRects[1] = TileIndex2Rectangle(new Point(1, 1));
            mDestRects[1] = new Rectangle(ScreenPosition.X + mTileSize.X,
                                          ScreenPosition.Y, Width - 2 * mTileSize.X, mTileSize.Y);
            // topRight
            mSrcRects[2] = TileIndex2Rectangle(new Point(2, 1));
            mDestRects[2] = new Rectangle(ScreenPosition.X - mTileSize.X + Width,
                                          ScreenPosition.Y, mTileSize.X, mTileSize.Y);
            // left
            mSrcRects[3] = TileIndex2Rectangle(new Point(0, 2));
            mDestRects[3] = new Rectangle(ScreenPosition.X,
                                          ScreenPosition.Y + mTileSize.Y, mTileSize.X, Height - 2 * mTileSize.Y);
            // middle
            mSrcRects[4] = TileIndex2Rectangle(new Point(1, 2));
            mDestRects[4] = new Rectangle(ScreenPosition.X + mTileSize.X,
                                          ScreenPosition.Y + mTileSize.Y, Width - 2 * mTileSize.X, Height - 2 * mTileSize.Y);
            // right
            mSrcRects[5] = TileIndex2Rectangle(new Point(2, 2));
            mDestRects[5] = new Rectangle(ScreenPosition.X - mTileSize.X + Width,
                                          ScreenPosition.Y + mTileSize.Y, mTileSize.X, Height - 2 * mTileSize.Y);
            // bottomLeft
            mSrcRects[6] = TileIndex2Rectangle(new Point(0, 3));
            mDestRects[6] = new Rectangle(ScreenPosition.X,
                                          ScreenPosition.Y - mTileSize.Y + Height, mTileSize.X, mTileSize.Y);
            // bottom
            mSrcRects[7] = TileIndex2Rectangle(new Point(1, 3));
            mDestRects[7] = new Rectangle(ScreenPosition.X + mTileSize.X, 
                                          ScreenPosition.Y - mTileSize.Y + Height, Width - 2 * mTileSize.X, mTileSize.Y);
            // bottomRight
            mSrcRects[8] = TileIndex2Rectangle(new Point(2, 3));
            mDestRects[8] = new Rectangle(ScreenPosition.X - mTileSize.X + Width, 
                                          ScreenPosition.Y - mTileSize.Y + Height, mTileSize.X, mTileSize.Y);
            // minimize
            var minPoint = new Point(0, 6);
            if (!HasCloseButton) minPoint.Y = 7; // this position is empty in the tiles texture
            mSrcRects[9] = TileIndex2Rectangle(minPoint);
            mDestRects[9] = new Rectangle(ScreenPosition.X - mTileSize.X + Width, 
                                          ScreenPosition.Y, mTileSize.X, mTileSize.Y);
        }

        private bool mMoving;
        private bool mResize;
        private Point mClickOffset = Point.Zero;

        protected internal override void MousePressEvent(MouseEvent evt)
        {
            if (!IsMouseOver) return;

            Point pos = evt.AbsolutePosition;

            mMoving = false;
            mResize = false;
            // Title bar
            if ((ScreenRectangle.Left < pos.X) &&
                (ScreenRectangle.Right > pos.X) &&
                ((ScreenRectangle.Top + mTileSize.Y) > pos.Y) &&
                (ScreenRectangle.Top < pos.Y))
            {
                mMoving = true;
                mClickOffset.X = Position.X - pos.X;
                mClickOffset.Y = Position.Y - pos.Y;
            }

            // lower right
            if (GeometryHelper.Contains(mDestRects[8], pos))
            {
                mMoving = false;
                mResize = true;
            }

            // close button
            if (mHasCloseButton &&
                GeometryHelper.Contains(mDestRects[9], pos))
            {
                Visible = !Visible;
            }
        }

        protected internal override void MouseReleaseEvent(MouseEvent evt)
        {
            mMoving = false;
            mResize = false;
        }

        protected internal override void MouseMoveEvent(MouseEvent evt)
        {
            Point pos = evt.AbsolutePosition;

            if (mMoving && mMoveable)
            {
                Position = new Point(mClickOffset.X + pos.X, 
                                     mClickOffset.Y + pos.Y);
 
                evt.Consume();
            }

            if (mResize && mResizable)
            {
                Vector2 size = Size;

                size.X += evt.RelativePosition.X;
                size.Y += evt.RelativePosition.Y;

                Size = size;

                evt.Consume();
            }

            // close button
            if (mHasCloseButton &&
                IsMouseOver && 
                GeometryHelper.Contains(mDestRects[9], pos))
            {
                mTileColors[9] = Color.White;
            }
            else
            {
                mTileColors[9] = Color.Tomato;
            }
        }

        protected internal override void MouseOverEvent(MouseEvent evt)
        {
            //TextColor = Color.Gray;
        }

        protected internal override void MouseOutEvent(MouseEvent evt)
        {
            //TextColor = Color.White;
        }
    }
}